#ifndef LEMC_TEXTBOX_H
#define LEMC_TEXTBOX_H

#include <vector>
#include <utility>

#include "../system/system.h"
#include "guielement.h"
#include "scrollbar.h"
#include "../system/global.h"
#include "../util/helpers.h"

struct TextBoxLine
{
	ALLEGRO_COLOR color;
	std::list<std::string> words;
};

struct TextBoxRow
{
	ALLEGRO_COLOR color;
	bool indent;
	std::string text;
};

/*
* A box that contains lines of text.
*/
class TextBox : public GuiElement
{
private:
	// The scrollbar.
	ScrollBar* m_scrollbar;

	// Contains all the lines.
	std::vector<TextBoxLine> m_line_list;

	// After an update cycle, this contains all the rows that have to be drawn.
	std::vector<TextBoxRow> m_rows_to_draw;

	// The distance of the scrollbar and the content from the border of the box.
	int m_padding;

	// The number of pixels that words should be indented if the line needs multiple rows.
	int m_indention;

	// The width of the scrollbar.
	int m_scrollbar_width;

	// The background graphic.
	std::string m_background_graphic;

	// The font for the text.
	ALLEGRO_FONT* m_text_font;

public:
	/*
	* Creates a box without text.
	*
	* @param id The id of the box. This should be unique.
	* @param x The x position of the upper left corner of the box.
	* @param y The y position of the upper left corner of the box.
	* @param size_x Horizontal size of the box.
	* @param size_y Vertical size of the box.
	* @param text_font The font for the box.
	* @param standard_color The standard color for the lines..
	* @param padding The distance from the border of the box.
	* @param indention The number of pixels that words should be indented if the line needs multiple rows.
	* @param background_graphic The background of the box.
	* @param scrollbar_width The width of the scrollbar.
	* @param scrollbar_button_height The height of the up and down buttons.
	* @param scrollbar_slider_padding The distance of the slider from the scrollbar borders.
	* @param scrollbar_slider_background_graphic The background graphic of the scrollbar.
	* @param scrollbar_slider_height The height of the slider.
	* @param scrollbar_slider_graphic_up The graphic of the slider, unpressed.
	* @param scrollbar_slider_graphic_down The graphic of the slider, pressed.
	* @param scrollbar_button_graphic_top_up The graphic of the top button, unpressed.
	* @param scrollbar_button_graphic_top_down The graphic of the top button, pressed.
	* @param scrollbar_button_graphic_bottom_up The graphic of the bottom button, unpressed.
	* @param scrollbar_button_graphic_bottom_down The graphic of the bottom button, pressed.
	*/
	TextBox(std::string id, int x, int y, int size_x, int size_y, ALLEGRO_FONT* text_font,
		int padding = STANDARD_TEXTBOX_PADDING, int indention = STANDARD_TEXTBOX_INDENTION,
		std::string background_graphic = STANDARD_TEXTBOX_BACKGROUND_GRAPHIC,
		int scrollbar_width = STANDARD_TEXTBOX_SCROLLBAR_WIDTH,
		int scrollbar_button_height = STANDARD_SCROLLBAR_BUTTON_HEIGHT,
		int scrollbar_slider_padding = STANDARD_SCROLLBAR_SLIDER_PADDING,
		std::string scrollbar_slider_background_graphic = STANDARD_SCROLLBAR_SLIDER_BACKGROUND_GRAPHIC,
		int scrollbar_slider_height = STANDARD_SCROLLBAR_SLIDER_HEIGHT,
		std::string scrollbar_slider_graphic_up = STANDARD_SCROLLBAR_SLIDER_GRAPHIC_UP,
		std::string scrollbar_slider_graphic_down = STANDARD_SCROLLBAR_SLIDER_GRAPHIC_DOWN,
		std::string scrollbar_button_graphic_top_up = STANDARD_SCROLLBAR_TOP_BUTTON_GRAPHIC_UP, 
		std::string scrollbar_button_graphic_top_down = STANDARD_SCROLLBAR_TOP_BUTTON_GRAPHIC_DOWN,
		std::string scrollbar_button_graphic_bottom_up = STANDARD_SCROLLBAR_BOTTOM_BUTTON_GRAPHIC_UP,
		std::string scrollbar_button_graphic_bottom_down = STANDARD_SCROLLBAR_BOTTOM_BUTTON_GRAPHIC_DOWN);
	~TextBox();

	/*
	* Adds a line to the list and adjusts the step value of the scrollbar correctly.
	*
	* @param text The text to add.
	* @param color The color of the text.
	*/
	void AddLine(std::string text, const unsigned char color[3] = STANDARD_TEXTBOX_TEXT_COLOR);

	void PrimaryMouseButtonUp(int x, int y);
	void PrimaryMouseButtonDown(int x, int y);
	void MouseAxisChange(int x, int y);

	void Update();
	void Draw();
};

#endif